export = {};

//排除
type Exclude<T,K> = T extends K ? never/*不留下*/ : T/*留下*/;
//在一系列类型中刨除掉某个类型可以使用
type ExcludeType = Exclude<string | number | boolean, number>; //string | boolean


//提取
type Extract<T,K> = T extends K ? T : never;
type ExtractType = Extract<string | number, string>; //string



//非空
let r = document.getElementById('app');
type NonNonNullableType = NonNullable<typeof r>; //HTMLElement

type NonNullable<T> = T extends null | undefined ? never : T;
//属性类型里用的多一点
//注意和!区别, !表示的是值,  值是非空的
//而 NonNullable代表的是类型非空


//history↓

/*type Diff<T, U> = T extends U ? never : T;  // Remove types from T that are assignable to U //TODO [notice] `never` 是对type编程里的null,undefined
type Filter<T, U> = T extends U ? T : never;  // Remove types from T that are not assignable to U

type T30 = Diff<"a" | "b" | "c" | "d", "a" | "c" | "f">;  // "b" | "d"
type T31 = Filter<"a" | "b" | "c" | "d", "a" | "c" | "f">;  // "a" | "c"
type T32 = Diff<string | number | (() => void), Function>;  // string | number
type T33 = Filter<string | number | (() => void), Function>;  // () => void

type NonNullable<T> = Diff<T, null | undefined>;  // Remove null and undefined from T

type T34 = NonNullable<string | number | undefined>;  // string | number
type T35 = NonNullable<string | string[] | null | undefined>;  // string | string[]

function f1<T>(x: T, y: NonNullable<T>) {
  x = y;  // Ok
  y = x;  // Error
}

function f2<T extends string | undefined>(x: T, y: NonNullable<T>) {
  x = y;  // Ok
  y = x;  // Error
  let s1: string = x;  // Error
  let s2: string = y;  // Ok
}*/
